﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace SFP.CollisionDetection
{
    public abstract class GlobalReaction
    {
        public const int MIN_OVERLAP = 0;
        public const int MAX_OVERLAP = 1;

        protected abstract void fromBeneath(HashSet<CollisionInfo> collisionCollisionInfos);
        protected abstract void fromAbove(HashSet<CollisionInfo> collisionCollisionInfos);
        protected abstract void fromLeft(HashSet<CollisionInfo> collisionCollisionInfos);
        protected abstract void fromRight(HashSet<CollisionInfo> collisionCollisionInfos);
        protected abstract void touchesTop(HashSet<CollisionInfo> collisionCollisionInfos);
        protected abstract void touchesBottom(HashSet<CollisionInfo> collisionCollisionInfos);
        protected abstract void touchesLeft(HashSet<CollisionInfo> collisionCollisionInfos);
        protected abstract void touchesRight(HashSet<CollisionInfo> collisionCollisionInfos);

        public void reactToCollision(long[] setIDs)
        {
            HashSet<CollisionInfo> collisionCollisionInfoSet = new HashSet<CollisionInfo>();
            foreach (long setID in setIDs)
            {
                HashSet<CollisionInfo> tempCollisionCollisionInfoSet;
                Collision.collisionInfoDict.TryGetValue(setID, out tempCollisionCollisionInfoSet);
                collisionCollisionInfoSet.UnionWith(tempCollisionCollisionInfoSet);
            }

            HashSet<CollisionInfo> collisionsFromAbove = null;
            HashSet<CollisionInfo> collisionsFromBeneath = null;
            HashSet<CollisionInfo> collisionsFromLeft = null;
            HashSet<CollisionInfo> collisionsFromRight = null;
            HashSet<CollisionInfo> collisionsTouchesTop = null;
            HashSet<CollisionInfo> collisionsTouchesBottom = null;
            HashSet<CollisionInfo> collisionsTouchesLeft = null;
            HashSet<CollisionInfo> collisionsTouchesRight = null;

            foreach (CollisionInfo collisionCollisionInfo in collisionCollisionInfoSet)
            {
                CollisionType collision = collisionCollisionInfo.Collision;

                if (collision == CollisionType.FromAbove)
                {
                    if (collisionsFromAbove == null) collisionsFromAbove = new HashSet<CollisionInfo>();
                    collisionsFromAbove.Add(collisionCollisionInfo);
                }
                else if (collision == CollisionType.TouchesTop)
                {
                    if (collisionsTouchesTop == null) collisionsTouchesTop = new HashSet<CollisionInfo>();
                    collisionsTouchesTop.Add(collisionCollisionInfo);
                }
                else if (collision == CollisionType.FromBeneathe)
                {
                    if (collisionsFromBeneath == null) collisionsFromBeneath = new HashSet<CollisionInfo>();
                    collisionsFromBeneath.Add(collisionCollisionInfo);
                }
                else if (collision == CollisionType.TouchesBottom)
                {
                    if (collisionsTouchesBottom == null) collisionsTouchesBottom = new HashSet<CollisionInfo>();
                    collisionsTouchesBottom.Add(collisionCollisionInfo);
                }
                else if (collision == CollisionType.FromLeft)
                {
                    if (collisionsFromLeft == null) collisionsFromLeft = new HashSet<CollisionInfo>();
                    collisionsFromLeft.Add(collisionCollisionInfo);
                }
                else if (collision == CollisionType.TouchesLeft)
                {
                    if (collisionsTouchesLeft == null) collisionsTouchesLeft = new HashSet<CollisionInfo>();
                    collisionsTouchesLeft.Add(collisionCollisionInfo);
                }
                else if (collision == CollisionType.FromRight)
                {
                    if (collisionsFromRight == null) collisionsFromRight = new HashSet<CollisionInfo>();
                    collisionsFromRight.Add(collisionCollisionInfo);
                }
                else if (collision == CollisionType.TouchesRight)
                {
                    if (collisionsTouchesRight == null) collisionsTouchesRight = new HashSet<CollisionInfo>();
                    collisionsTouchesRight.Add(collisionCollisionInfo);
                }
            }

            if (collisionsFromBeneath != null)
            {
                fromBeneath(collisionsFromBeneath);
            }
            if (collisionsFromAbove != null)
            {
                fromAbove(collisionsFromAbove);
            }
            if (collisionsFromLeft != null)
            {
                fromLeft(collisionsFromLeft);
            }
            if (collisionsFromRight != null)
            {
                fromRight(collisionsFromRight);
            }
            if (collisionsTouchesTop != null)
            {
                touchesTop(collisionsTouchesTop);
            }
            if (collisionsTouchesBottom != null)
            {
                touchesBottom(collisionsTouchesBottom);
            }
            if (collisionsTouchesLeft != null)
            {
                touchesLeft(collisionsTouchesLeft);
            }
            if (collisionsTouchesRight != null)
            {
                touchesRight(collisionsTouchesRight);
            }
        }
    }
}
